package person.bing.fbcloud.common.log.aop;

import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import person.bing.fbcloud.common.core.enums.StatuEnums;
import person.bing.fbcloud.common.log.annotation.SysLog;
import person.bing.fbcloud.common.log.event.SysLogEvent;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * @author: mengfanbing
 * @date: 2020/5/18 12:26
 * 操作日志记录
 */
@Aspect
@AllArgsConstructor
public class SysLogAop {
    private final ApplicationEventPublisher publisher;

    @SneakyThrows
    @Around("@annotation(sysLog)")
    public Object save(ProceedingJoinPoint point, SysLog sysLog){
        LocalDateTime now = LocalDateTime.now();
        String className = point.getTarget().getClass().getName();
        String methodName = point.getSignature().getName();

        long startTime = System.currentTimeMillis();
        Object proceed = point.proceed();
        long endTime = System.currentTimeMillis();
        //发送异步日志时间
        person.bing.fbcloud.entity.SysLog log = this.getSysLog();
        log.setCostTime(endTime-startTime);
        log.setLogDesc(sysLog.value());
        log.setPath(className.concat(StrUtil.DOT).concat(methodName));
        log.setCreateTime(now);
        log.setUpdateTime(now);
        publisher.publishEvent(new SysLogEvent(log));
        return proceed;
    }

    private person.bing.fbcloud.entity.SysLog getSysLog(){
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();

        //测试HttpServletRequest可以获取到哪些信息
        String protocol = request.getProtocol();
        System.out.println("协议及版本protocol=" + protocol);
        String serverName = request.getServerName();
        System.out.println("服务端主机名serverName=" + serverName);
        int serverPort = request.getServerPort();
        System.out.println("服务端端口serverPort=" + serverPort);

        person.bing.fbcloud.entity.SysLog sysLog = new person.bing.fbcloud.entity.SysLog();
        sysLog.setStatu(StatuEnums.STATU_YES.getStatu());
        sysLog.setParams(HttpUtil.toParams(request.getParameterMap()));
        sysLog.setRequestMethod(request.getMethod());
        sysLog.setRemoteAddr(HttpUtil.getClientIP(request));
        sysLog.setRequestUri(URLUtil.getPath(request.getRequestURI()));
        sysLog.setUserAgent(request.getHeader("user-agent"));
//        sysLog.setServiceId()
//        sysLog.setCreateBy()
        return sysLog;
    }
}
